/*
 * EP-Tracing System : a tool to trace mountain hike.           .kNNx
 * Copyright (C) 2009  Raffaello Brondi                         'KNNNk
 *                                                             ,XNNNl
 * This program is free software:                             ,XNN0'
 * you can redistribute it and/or modify                     ,XNNx.
 * it under the terms of the                                'XNNl
 * GNU General Public License                              .KNN:                     ..
 * as published by                                        .0NNo                    .ONNO.
 * the Free Software Foundation,                          xNNN.  :dkd,            .KNNNN;
 * either version 3 of the License, or                   :NNNK ;XNNNNNo          ,KNNNX:
 * (at your option) any later version.                   xNNNNcXNNNNNNk         cNNNNx.
 *                                                       ,XNNNNNNNNNNX'       .xNNNK;
 *                                                        .lKNNNNNNNK'       :KNNNo
 *                                                          ;kNNNNNKxl;'.'l0NNNk.
 * This program is distributed in                          .'  .:xXNNNNNNNNNNNO,
 * the hope that it will be useful,                       :NNXd'   ,oONNNNNNk,
 * but WITHOUT ANY WARRANTY;                              xNNNNN0c.    .;;,.
 * without even the implied warranty of                   kNNNNNNNXd'
 * MERCHANTABILITY or                                     xNNNNNNNNNNOc.
 * FITNESS FOR A PARTICULAR PURPOSE.                      xNNNNNNNNNNNNXd.
 * See the GNU General Public License                     ONNNN0.,o0NNNNNNl
 * for more details.                                      0NNNNd    kNNNNNX.
 *                                                        KNNNNl   oNNNNNXc
 *                                                       .XNNNN:  dNNNNNx.
 * You should have received a copy                       .XNNNN; lNNNNO'
 * of the GNU General Public License                     .XNNNN; 'dxo'
 * along with this program.                              .XNNNN;
 * If not, see <http://www.gnu.org/licenses/>.            0NNNN:
 *                                                        kNNNNc
 *                                                        oNNNNd
 *                                                        ;NNNN0
 * Contact: rbrondi@gmail.com                             .XNNNN;
 *                                                         kNNNNd
 *                                                         .coo:.
 */
package EP.UI.Compass;

import EP.FileSystemManager;
import EP.UI.EPTS;
import EP.UI.Messages;
import java.io.IOException;
import java.util.Enumeration;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.io.file.FileSystemListener;
import javax.microedition.io.file.FileSystemRegistry;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;

/**
 *
 * @author Raffaello Brondi
 */
public class EPHLoader extends List implements FileSystemListener {

    /* Up directory */
    private static final String UP_DIR = "..";
    /* Root folder */
    private static final String ROOT = "/";
    /* The title of the list */
    private static final String TITLE = "Choose an hike.";
    /* The application file extension */
    private static final String EPH_EXT = "eph";

    /* File separator character */
    private static final char FILE_SEPARATOR = System.getProperty("file.separator") != null ? System.getProperty("file.separator").charAt(0) : '/';
    private String current;
    private Command loadCommand = new Command("Load", Command.OK, 1);
    private Command detailsCommand = new Command("Details", Command.ITEM, 1);
    private Command exitCommand = new Command("Back", Command.BACK, 2);
    private Image folder;
    private Image eph;
    private CommandListener listener;

    /**
     * Checks whether the name passed as parameter is of a folder or not.
     * @param name The name of the FileSystem entity to be tested.
     * @return <b>true</b> if it is a folder, <b>false</b> otherwise.
     */
    private static boolean isFolder(String name) {
        return name.charAt(name.length() - 1) == FILE_SEPARATOR ? true : false;
    }

    /**
     * Checks if the file name specified has an "<i>.eph</i>" extension.
     * @param name The name of the file to be tested.
     * @return <b>true</b> if it is an "<i>.eph</i>" file, <b>false</b> otherwise.
     */
    private static boolean isEPH(String name) {
        if (name.length() < 4) {
            return false;
        }
        System.out.println(name.substring(name.length() - 3));
        return name.substring(name.length() - 3).equals(EPH_EXT) ? true : false;
    }

    public EPHLoader(CommandListener listener) {
        super(TITLE, Choice.IMPLICIT);
        this.current = ROOT;
        try {
            this.folder = Image.createImage("/folder.png");
        } catch (IOException ex) {
            ex.printStackTrace();
            this.folder = null;
        }

        try {
            this.eph = Image.createImage("/ephFileIcon.png");
        } catch (IOException ex) {
            ex.printStackTrace();
            this.folder = null;
        }
        FileSystemRegistry.addFileSystemListener(this);

        this.setCommandListener(listener);

        this.addCommand(this.loadCommand);
        this.addCommand(this.detailsCommand);
        this.addCommand(this.exitCommand);

        this.listener = listener;

        this.updateTree();
    }

    public Command getLoadCommand() {
        return this.loadCommand;
    }

    public Command getDetailsCommand() {
        return this.detailsCommand;
    }

    public Command getExitCommand() {
        return this.exitCommand;
    }

    /**
     * Resets the browser to point to the root FileSystem folder.
     */
    public void reset() {
        this.current = ROOT;
        this.updateTree();
        return;
    }

    private void updateTree() {
        Enumeration entities;
        FileConnection currDir = null;
        this.deleteAll();
        System.out.println("actual folder : " + this.current);
        try {
            if (ROOT.equals(this.current)) {
                entities = FileSystemManager.getInstance().getRoots().elements();
            } else {
                currDir = (FileConnection) Connector.open("file://" + this.current);
                entities = currDir.list();

                this.append(UP_DIR, this.folder);
            }

            while (entities.hasMoreElements()) {
                String fileName = (String) entities.nextElement();

                if (EPHLoader.isFolder(fileName)) {
                    this.append(fileName, this.folder);
                }
                if (EPHLoader.isEPH(fileName)) {
                    this.append(fileName, this.eph);
                }
            }

            if (currDir != null) {
                currDir.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void load() {
        String selected = this.getString(this.getSelectedIndex());
        if (EPHLoader.isFolder(selected)) {
            Messages.showNotLoadableFile();
        }
    }

    public void showEPHDetails() {
        String selected = this.getString(this.getSelectedIndex());
        if (!EPHLoader.isEPH(selected)) {
            Messages.showNoDetails4File();
        } else {
            System.out.println(this.current + selected);
            EPHDetailsViewer viewer = new EPHDetailsViewer(this.current + selected, this.listener);
            EPTS.getDisplay().setCurrent(viewer);
        }
    }

    public void openFolder() {
        String selected = this.getString(this.getSelectedIndex());
        if (!selected.equals(UP_DIR) && !EPHLoader.isFolder(selected)) {
            this.showEPHDetails();
        } else {
            if (selected.equals(UP_DIR)) {
                int i = this.current.lastIndexOf(FILE_SEPARATOR, this.current.length() - 2);
                if (i != -1) {
                    this.current = this.current.substring(0, i + 1);
                } else {
                    this.current = ROOT;
                }
            } else {
                this.current = this.current + selected;
            }

            this.updateTree();
        }
    }

    public void rootChanged(int arg0, String arg1) {
        this.updateTree();
    }
}